<template>
  <view
    class="tn-tips tn-text-ellipsis-1"
    :class="[tipsClass]"
    :style="tipsStyle"
  >
    {{ tipsContent }}
  </view>
</template>

<script lang="ts" setup>
import { tipsProps, tipsEmits, TipsOption } from '../../../types/tn-tips'
import { ColorInfo, TuniaoType } from '../../../types/tuniao-ui'
import { ref, computed, watchEffect, CSSProperties } from 'vue'
import useComponentColor from '../../../libs/hooks/useComponentColor'
import { handleValueWithUnit } from '../../../utils'

const props = defineProps(tipsProps)
const emits = defineEmits(tipsEmits)

const { splitColorInfo } = useComponentColor()
// 背景颜色
let bgColor = computed<ColorInfo>(() => {
  return splitColorInfo('bg', optionBgColor.value || '')
})
let optionBgColor = ref<string>('')
// 字体颜色
let color = computed<ColorInfo>(() => {
  return splitColorInfo('color', optionColor.value || '')
})
let optionColor = ref<string>('')
// 内置类型
let type = ref<TuniaoType | ''>('')

// tips样式
const tipsStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  if (props?.zIndex) style.zIndex = Number(props.zIndex)
  if (bgColor.value.type === 'style') style.backgroundColor = bgColor.value.value
  if (color.value.type === 'style') style.color = color.value.value
  // 判断位置
  if (props.position === 'top') {
    if (typeof props.top !== 'undefined') style.top = handleValueWithUnit(props.top)
    if (showTips.value) {
      style.transform = 'translateY(0%)'
    } else {
      style.transform = 'translateY(-100%)'
    }
  } else if (props.position === 'center') {
    style.top = '50%'
    style.left = '50%'
    if (showTips.value) {
      style.transform = 'translate(-50%, -50%) scale(1)'
    } else {
      style.transform = 'translate(-50%, -50%) scale(0)'
    }
  } else if (props.position === 'bottom') {
    style.bottom = '10%'
    style.left = '50%'
    if (showTips.value) {
      style.transform = 'translate(-50%, -50%) scale(1)'
    } else {
      style.transform = 'translate(-50%, -50%) scale(0)'
    }
  }
  return style
})

// tips对应的类
const tipsClass = computed<string>(() => {
  let clazz: string[] = []
  clazz.push(`tn-tips--${props.position}`)
  if (visibleTips.value) clazz.push('visible')
  if (bgColor.value.type === 'class') clazz.push(bgColor.value.value)
  if (color.value.type === 'class') clazz.push(color.value.value)
  if (type.value) clazz.push(`tn-type-${type.value}--light`)
  return clazz.join(' ')
})

// 显示tips提示框
let visibleTips = ref<boolean>(false)
let showTips = ref<boolean>(false)
// 提示内容
let tipsContent = ref<string>('')
// tips关闭定时器
let timer: number | null
// 显示tips框
const show = (option: TipsOption) => {
  // 如果没有设置内容则不显示
  if (!option?.msg) {
    resetTipsInfo()
    return
  }
  resetTimer()
  resetTipsInfo()
  const duration = option?.duration || 2000

  tipsContent.value = option.msg || ''
  optionBgColor.value = option?.bgColor || ''
  optionColor.value = option?.color || ''
  type.value = option?.type || ''
  setTipsStatus(true)

  timer = setTimeout(() => {
    setTipsStatus(false)
    resetTimer()
  }, duration);
}

// 设置tips显示状态
const setTipsStatus = (status: boolean) => {
  if (status) {
    visibleTips.value = true
    showTips.value = true
  } else {
    showTips.value = false
    visibleTips.value = false
    emits('closed')
  }
}

// 重置定时器
const resetTimer = () => {
  if (timer) {
    clearTimeout(timer)
    timer = null
  }
}
// 重置设置信息
const resetTipsInfo = () => {
  visibleTips.value = false
  showTips.value = false
  tipsContent.value = ''
  optionBgColor.value = ''
  optionColor.value = ''
}

defineExpose({
  show
})
</script>

<script lang="ts">
export default {
  options: {
    // 在微信小程序中将组件节点渲染为虚拟节点，更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
    virtualHost: true
  }
}
</script>

<style lang="scss" scoped>
@import '../../../theme.scss';

.tn-tips {
  height: fit-content;
  position: fixed;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform,opacity 0.25s ease-out;
  visibility: hidden;
  opacity: 0;
  overflow: hidden;
  background-color: $tn-main-color;
  color: #FFFFFF;

  &.visible {
    visibility: visible;
    opacity: 1;
  }

  &--top {
    width: 100%;
    padding: 4rpx 8rpx;
    transform-origin: top center;
    
  }
  &--center, &--bottom {
    width: fit-content;
    padding: 18rpx 30rpx;
    border-radius: 8rpx;
    transform-origin: center center;
  }
}
</style>
